package cn.utry.sipGateWay.sip;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import io.netty.util.internal.StringUtil;

public class SipMessageUtil {
	public static String method = "method";
	public static String msgType = "messageType";
	public static String responseCode = "stateCode";
	public static String append01 = "\r\n";
	public static String append02 = ": ";
	public static String append03 = " ";
	public static String blank = "\\s+";
	public static String SIP = "SIP/2.0";
	public static String splitStr = "@";

	public static Map reciveMsg(String msg) {
		Map<String, Object> map = new HashMap<>();
		map.put(SipMsgKey.SDP, "");
		BufferedReader br = new BufferedReader(new InputStreamReader(
				new ByteArrayInputStream(msg.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));
		try {
			Integer count = 0;
			String line = null;
			boolean isEmpty = false;
			while ((line = br.readLine()) != null) {
				count = count + 1;
				if (count == 1) {
					// 第一行信息 SIP/2.0结尾的是摄像头请求信息
					if (line.endsWith(SIP)) {
						// 获取消息类型
						map.put(method, line.split(blank)[0].trim());
						map.put(SipMsgKey.URL, line.split(blank)[1].trim());
						map.put(msgType, MsgKey.REQUEST);
						continue;
					}
					// SIP/2.0开头的是摄像头响应的信息
					if (line.startsWith(SIP)) {
						// 响应码获取
						map.put(responseCode, line.split(blank)[1]);
						// 消息类型
						map.put(method, line.split(blank)[2].trim());
						map.put(msgType, MsgKey.RESPONSE);
						continue;
					}
				} else {
					line = line.trim();
					if (!isEmpty) {
						if (!line.isEmpty()) {
							// 冒号加空格切割请求头属性和值
							String[] s = line.split(": ");
							String key = s[0].trim();
							String value = s[1].trim();
							// 第一个是请求头名称，第二个是值
							if (map.containsKey(key)) {
								if (map.get(key) instanceof String) {
									List<String> list = new LinkedList();
									list.add(map.get(key).toString());
									list.add(value);
									map.put(key, list);
								} else {
									List<String> list = (List<String>) map.get(key);
									list.add(value);
									map.put(key, list);
								}
							} else {
								map.put(key, value);
							}
							// From请求头,如果是请求信息，通常设备编号在这里获取
						} else {
							isEmpty = true;
						}
					} else {
						if (!line.isEmpty()) {
							String sdp = (String) map.get(SipMsgKey.SDP);
							sdp = sdp + line + append01;
							map.put(SipMsgKey.SDP, sdp);
						}
					}

				}

			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return map;
	}

	public static String getInviteMsg(Map<String, Object> map, String fromIp, String toIp) {
		StringBuffer str = new StringBuffer("");
		if (map.get(method).equals(SipMethod.INVITE)) {
			String dstIp = map.get(SipMsgKey.DST).toString();
			String url = map.get(SipMsgKey.URL).toString();
			url = url.replace(dstIp, toIp);
			str.append(SipMethod.INVITE).append(append03).append(url).append(append03).append(SIP).append(append01);
			if (map.containsKey(SipMsgKey.Via)) {
				String via = map.get(SipMsgKey.Via).toString();
				via = via.replace(map.get(SipMsgKey.SRC) + ":" + map.get(SipMsgKey.SRC_PORT),
						map.get(SipMsgKey.SRC) + ":1" + map.get(SipMsgKey.SRC_PORT));
				str.append(SipMsgKey.Via).append(append02).append(via).append(append01);
			}
			if (map.containsKey(SipMsgKey.From)) {
				String from = map.get(SipMsgKey.From).toString();
				from = from.replace(dstIp, toIp);
				str.append(SipMsgKey.From).append(append02).append(from).append(append01);
			}
			if (map.containsKey(SipMsgKey.To)) {
				String to = map.get(SipMsgKey.To).toString();
				to = to.replace(dstIp, toIp);
				str.append(SipMsgKey.To).append(append02).append(to).append(append01);
			}
			if (map.containsKey(SipMsgKey.Call_ID)) {
				str.append(SipMsgKey.Call_ID).append(append02).append(map.get(SipMsgKey.Call_ID)).append(append01);
			}
			if (map.containsKey(SipMsgKey.CSeq)) {
				str.append(SipMsgKey.CSeq).append(append02).append(map.get(SipMsgKey.CSeq)).append(append01);
			}
			if (map.containsKey(SipMsgKey.Contact)) {
				String concat = map.get(SipMsgKey.Contact).toString();
				concat = concat.replace(map.get(SipMsgKey.SRC) + ":" + map.get(SipMsgKey.SRC_PORT),
						map.get(SipMsgKey.SRC) + ":1" + map.get(SipMsgKey.SRC_PORT));
				str.append(SipMsgKey.Contact).append(append02).append(concat).append(append01);
			}
			if (map.containsKey(SipMsgKey.Allow)) {
				str.append(SipMsgKey.Allow).append(append02).append(map.get(SipMsgKey.Allow)).append(append01);
			}
			if (map.containsKey(SipMsgKey.Max_Forwards)) {
				str.append(SipMsgKey.Max_Forwards).append(append02).append(map.get(SipMsgKey.Max_Forwards))
						.append(append01);
			}
			if (map.containsKey(SipMsgKey.User_Agent)) {
				str.append(SipMsgKey.User_Agent).append(append02).append(map.get(SipMsgKey.User_Agent))
						.append(append01);
			}
			if (map.containsKey(SipMsgKey.Content_Type)) {
				str.append(SipMsgKey.Content_Type).append(append02).append(map.get(SipMsgKey.Content_Type))
						.append(append01);
			}
			String sdp = map.get(SipMsgKey.SDP).toString();
			if (map.get(SipMsgKey.SDP).equals("")) {
				str.append("Content-Length").append(append02).append(sdp.length()).append(append01);
			} else {
				str.append("Content-Length").append(append02).append(sdp.length()).append(append01).append(append01);
				sdp=sdp.replace("a=sendrecv", "a=sendonly");
				str.append(sdp);
				
			}
		}
		return str.toString();
	}

	public static String getAckMsg(Map<String, Object> map) {
		StringBuffer str = new StringBuffer("");
		String url = map.get(SipMsgKey.URL).toString();
		url=url.replace("<", "").replace(">", "");		
		str.append(SipMethod.ACK).append(append03).append(url).append(append03).append(SIP).append(append01);
		str.append(SipMsgKey.To).append(append02).append(map.get(SipMsgKey.To)).append(append01);
		str.append(SipMsgKey.From).append(append02).append(map.get(SipMsgKey.From)).append(append01);
		str.append(SipMsgKey.Via).append(append02).append(map.get(SipMsgKey.Via)).append(append01);
		str.append(SipMsgKey.Call_ID).append(append02).append(map.get(SipMsgKey.Call_ID)).append(append01);
		if (map.containsKey(SipMsgKey.CSeq)) {
			String cSeq = map.get(SipMsgKey.CSeq).toString();
			cSeq = cSeq.replace("INVITE", "ACK");
			str.append(SipMsgKey.CSeq).append(append02).append(cSeq).append(append01);
		}
		if (map.containsKey(SipMsgKey.Route)) {
			if (map.get(SipMsgKey.Route) instanceof String) {
				str.append(SipMsgKey.Route).append(append02).append(map.get(SipMsgKey.Route)).append(append01);
			} else {
				LinkedList list = (LinkedList) map.get(SipMsgKey.Route);
				ListIterator it = list.listIterator(list.size());
				while (it.hasPrevious()) {
					Object object = it.previous();
					str.append(SipMsgKey.Route).append(append02).append(object).append(append01);
				}
			}
		}
		if (map.containsKey(SipMsgKey.Record_Route)) {
			if (map.get(SipMsgKey.Record_Route) instanceof String) {
				str.append(SipMsgKey.Route).append(append02).append(map.get(SipMsgKey.Record_Route)).append(append01);
			} else {
				LinkedList<String> list = (LinkedList) map.get(SipMsgKey.Record_Route);
				ListIterator<String> it = list.listIterator(list.size());
				int i=0;
				while (it.hasPrevious()) {
					String obj = it.previous();
					if(i==0) {
						obj=obj.replace("lr=on", "lr");
					}
					str.append(SipMsgKey.Route).append(append02).append(obj).append(append01);
					i++;
				}
			}
		}
		if (map.containsKey(SipMsgKey.Contact)) {
			String concat = map.get(SipMsgKey.Contact).toString();
			concat = concat.replace(map.get(SipMsgKey.SRC) + ":" + map.get(SipMsgKey.SRC_PORT),
					map.get(SipMsgKey.SRC) + ":1" + map.get(SipMsgKey.SRC_PORT));
			str.append(SipMsgKey.Contact).append(append02).append(concat).append(append01);
		}
		str.append(SipMsgKey.Max_Forwards).append(append02).append("70").append(append01);
		if (map.containsKey(SipMsgKey.User_Agent)) {
			str.append(SipMsgKey.User_Agent).append(append02).append(map.get(SipMsgKey.User_Agent)).append(append01);
		}
		str.append("Content-Length").append(append02).append("0").append(append01).append(append01);
		return str.toString();
	}
	public static int getRtpPort(Map<String, Object> map) {
		String split="m=audio";
		int port=0;
		String sdp=map.get(SipMsgKey.SDP).toString();
		if(StringUtil.isNullOrEmpty(sdp)) {
			String portStr=sdp.split(split)[1].trim().split(blank)[0].trim();
			port=Integer.parseInt(portStr);
		}
		return port;
	}
}
